package com.fuluwa.domain.shared;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.hibernate.HibernateException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.transaction.annotation.Transactional;

import com.fuluwa.infra.exception.PersistenceException;

class DataAccess implements InitializingBean {
	@PersistenceContext
	private EntityManager entityManager;
	private static DataAccess instance = new DataAccess();

	public static DataAccess getInstance() {
		return instance;
	}

	@Transactional
	public void save(Object entity) throws PersistenceException {

		try {
			entityManager.persist(entity);
		} catch (HibernateException e) {
			throw HibernateExceptionTranslator.translate(e, "Save Error");
		}
	}

	@Transactional
	public void update(Object entity) throws PersistenceException {
		try {
			entityManager.merge(entity);
		} catch (HibernateException e) {
			throw HibernateExceptionTranslator.translate(e, "Update Error");
		}
	}

	@Transactional
	public void delete(Object entity) throws PersistenceException {
		try {
			entityManager.remove(entity);
		} catch (HibernateException e) {
			throw HibernateExceptionTranslator.translate(e, "Delete Error");
		}
	}

	@Transactional(readOnly = true)
	public <T> T find(Class<T> entityClass, Object primaryKey) throws PersistenceException {
		try {
			return entityManager.find(entityClass, primaryKey);
		} catch (HibernateException e) {
			throw HibernateExceptionTranslator.translate(e, "Find Error");
		}
	}

	public void detach(Object entity) {
		entityManager.detach(entity);
	}

	@Transactional(readOnly = true)
	public int count(Class<?> entityClass) throws PersistenceException {
		try {
			Object count = entityManager.createQuery("select count(a) from " + entityClass.getName() + " as a")
					.getSingleResult();
			return Integer.valueOf(count.toString());
		} catch (HibernateException e) {
			throw HibernateExceptionTranslator.translate(e, "Count Error");
		}
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		instance = this;
	}

}
